package com.xhwl.centiotdata.suppliersystem.eesd.lanju;

import cn.hutool.core.collection.CollectionUtil;
import com.alibaba.fastjson.JSON;
import com.google.common.collect.Lists;
import com.mashape.unirest.http.HttpResponse;
import com.mashape.unirest.http.Unirest;
import com.xhwl.centiotdata.pojo.dto.eesd.EesdConfigDTO;
import com.xhwl.centiotdata.pojo.enums.eesd.EesdMethodEnum;
import com.xhwl.centiotdata.pollingtrigger.eesd.EesdDispatcher;
import com.xhwl.centiotdata.service.cent.IBiEnvCentService;
import com.xhwl.centiotdata.service.cent.ICentAlarmService;
import com.xhwl.centiotdata.service.cent.IDeviceCentService;
import com.xhwl.centiotdata.service.integrateconfig.EESDIntegrationConfig;
import com.xhwl.common.dto.cent.device.DeviceDTO;
import com.xhwl.common.enums.device.DeviceOnlineStatusEnum;
import com.xhwl.common.pojo.ResultJson;
import com.xhwl.common.pojo.cent.bi.DwdFactEnvironmentMetrics;
import com.xhwl.common.pojo.cent.device.Device;
import com.xhwl.common.pojo.cent.device.DeviceProjSupplierCategory;
import com.xhwl.common.query.cent.device.DevicePageQuery;
import com.xhwl.common.utils.ChkUtil;
import com.xhwl.common.utils.DateUtils;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;

import java.nio.charset.StandardCharsets;
import java.util.Collections;
import java.util.List;
import java.util.Map;

/**
 * @Author： lianghz
 * @Description：
 * @Date 2021/09/03/ 09:44
 */
@Slf4j
@RestController
public class LanjuApiHandler {

    @Autowired
    private EesdDispatcher eesdDispatcher;

    @Autowired
    private IDeviceCentService iDeviceCentService;

    @Autowired
    private ICentAlarmService iCentAlarmService;

    @Autowired
    private EESDIntegrationConfig integrationConfig;

    @Autowired
    private IBiEnvCentService biEnvCentService;

    @Autowired
    private EESDIntegrationConfig eesdIntegrationConfig;

    private static ThreadLocal<List<Map<String, Object>>> threadLocal = new ThreadLocal<>();

    public static ThreadLocal<List<Map<String, Object>>> getThreadLocal() {
        return threadLocal;
    }

    /**
     * 实际处理逻辑
     */
    public void pullRecord(EesdConfigDTO eesdConfigDTO) {
        try {
            String host = eesdConfigDTO.getHost().replace("{deviceId}", eesdConfigDTO.getDeviceId());

            Unirest.setTimeouts(0, 0);
            HttpResponse<String> response = Unirest.get(host).asString();
            String res = new String(response.getBody().getBytes("gbk"), StandardCharsets.UTF_8);
            Map<String, Object> map = JSON.parseObject(res);
            List<Map<String, Object>> data = (List<Map<String, Object>>) map.get("data");
            if (CollectionUtil.isEmpty(data)) {
                threadLocal.set(Lists.newArrayList());
                return;
            }
            threadLocal.set(data);
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    private EesdConfigDTO getConfig(Integer projectId) {
        if (projectId == null)
            return null;
        List<EesdConfigDTO> eesdConfigs = integrationConfig.getIntegrationConfig(EesdMethodEnum.LANJU.getId());
        for (EesdConfigDTO eesdConfig : eesdConfigs) {
            if (eesdConfig.getProjectId().equals(projectId)) {
                return eesdConfig;
            }
        }
        return null;
    }

    /**
     * 对外接口
     */
    @RequestMapping(value = "/lanju/pull")
    public ResultJson pullInfo(@RequestParam(value = "projectId") Integer projectId) {
        EesdConfigDTO config = getConfig(projectId);
        if (config == null)
            return ResultJson.fail("找不到对应projectId");
        //此处只执行数据拉取
        pullRecord(config);
        List<Map<String, Object>> eesdLanJuVO = threadLocal.get();
        threadLocal.remove();
        if (eesdLanJuVO == null) {
            return ResultJson.success(Lists.newArrayList());
        }
        //判断设备在离线状态
        for (Map<String, Object> map : eesdLanJuVO) {
            map.put("ONLINE", "离线");
            DevicePageQuery devicePageQuery = new DevicePageQuery();
            devicePageQuery.setProjectId(projectId);
            devicePageQuery.setDeviceTypeId(8);
            //默认机器编码
            devicePageQuery.setThirdDeviceId(config.getDeviceId());
            List<DeviceDTO> devices = iDeviceCentService.listDevice(null, devicePageQuery);
            if (ChkUtil.isNotNull(devices) && ChkUtil.isNotNull(devices.get(0).getOnlineStatus())) {
                Integer onlineStatus = devices.get(0).getOnlineStatus();
                map.put("ONLINE", onlineStatus == 1 ? "在线" : "离线");
            }
        }
        return ResultJson.success(eesdLanJuVO);
    }

    /**
     * 获取当前所有蓝居设备
     *
     * @param projectId
     * @return
     */
    public List<DeviceDTO> getLanjuDevice(Integer projectId) {
        DevicePageQuery devicePageQuery = new DevicePageQuery();
        devicePageQuery.setProjectId(projectId);
        devicePageQuery.setDeviceTypeId(EesdMethodEnum.LANJU.getId());
        List<DeviceDTO> devices = iDeviceCentService.listDevice(null, devicePageQuery);
        return devices;
    }


    /**
     * 蓝居拉取环境数据
     *
     * @param config
     */
    public List<DwdFactEnvironmentMetrics> pullEnvRecord(DeviceProjSupplierCategory config) {
        List<DwdFactEnvironmentMetrics> list = LanjuApiUtil.pullEnvRecord(config);
        return list;
    }


    public Object pullEnvDevice(DeviceProjSupplierCategory config) {
        EesdConfigDTO eesdConfigDTO = getConfig(config.getProjectId());
        return pullEnvDevice(eesdConfigDTO);
    }


    /**
     * 同步蓝居设备状态，并查询在离线状态发出告警
     */
    public Object pullEnvDevice(EesdConfigDTO eesdConfigDTO) {
        Map data;
        try {
            String envHost = eesdConfigDTO.getEnvHost();
            log.info("pullEnvDevice envHost=" + envHost);
            Unirest.setTimeouts(0, 0);
            HttpResponse<String> response = Unirest.get(envHost).asString();
            String res = new String(response.getBody().getBytes(StandardCharsets.UTF_8), StandardCharsets.UTF_8);
            log.info("pullEnvDevice res=" + res);
            Map map = JSON.parseObject(res, Map.class);
            if (map == null) {
                throw new RuntimeException("查询失败");
            }
            data = (Map) map.get("data");
        } catch (Exception e) {
            e.printStackTrace();
            changeOffStatus(eesdConfigDTO);
            return null;
        }
        String deviceId = ChkUtil.getString(data.get("device_id"));
        String deviceName = ChkUtil.getString(data.get("device_name"));
        String isOnline = ChkUtil.getString(data.get("is_online"));
        String registerTime = ChkUtil.getString(data.get("register_time"));
        List location = (List) data.get("location");
        if (deviceId == null) {
            changeOffStatus(eesdConfigDTO);
            return null;
        }
        DeviceDTO query = new DeviceDTO();
        query.setProjectId(eesdConfigDTO.getProjectId());
        query.setThirdDeviceId(deviceId);
        query.setName(deviceName);
        query.setDeviceTypeId(8);
        query.setCategoryId(8);
        query.setDeviceStatus(1);
        query.setProductId(EesdMethodEnum.LANJU.getId());
        int onlineStatus = "在线".equalsIgnoreCase(isOnline) ? 1 : 0;
        query.setOnlineStatus(onlineStatus);
        if (location != null) {
            query.setLongitude(ChkUtil.getString(location.get(0)));
            query.setLatitude(ChkUtil.getString(location.get(1)));
        }
        query.setAttributeJson(JSON.parseObject(JSON.toJSONString(data)));
        query.setCreatedAt(DateUtils.getFormatDate(registerTime));
        List<DeviceDTO> deviceDTOList = Collections.singletonList(query);

        iDeviceCentService.asyncUpdateDevice(deviceDTOList);

        Device device = new Device();
        device.setProjectId(eesdConfigDTO.getProjectId());
        device.setThirdDeviceId(deviceId);
        device.setDeviceTypeId(8);
        device.setOnlineStatus(onlineStatus == 1 ? DeviceOnlineStatusEnum.ONLINE : DeviceOnlineStatusEnum.OFFLINE);
        List<Device> deviceList = Collections.singletonList(device);
        //测试环境，cent-device版本太低，asyncUpdateDevice不支持更新在离线，所以调用老接口更新，上面的接口新增和修改数据
        //todo 测试环境cent-device更新后，这个方法可以删除
        iDeviceCentService.asyncUpdateOnlineStatus(deviceList);
        log.info("同步蓝居设备数据:" + deviceDTOList.toString());
        return data;
    }


    /**
     * 环境设备异常变成离线
     */
    private void changeOffStatus(EesdConfigDTO eesdConfigDTO) {
        DevicePageQuery devicePageQuery = new DevicePageQuery();
        devicePageQuery.setProjectId(eesdConfigDTO.getProjectId());
        devicePageQuery.setDeviceTypeId(8);
        devicePageQuery.setThirdDeviceId(eesdConfigDTO.getDeviceId());
        List<DeviceDTO> devices = iDeviceCentService.listDevice(null, devicePageQuery);
        if (ChkUtil.isNotNull(devices)) {
            for (DeviceDTO device : devices) {
                Device query = new Device();
                query.setProjectId(eesdConfigDTO.getProjectId());
                query.setThirdDeviceId(device.getThirdDeviceId());
                query.setDeviceTypeId(22);
                query.setOnlineStatus(DeviceOnlineStatusEnum.OFFLINE);
                List<Device> deviceList = Collections.singletonList(query);
                iDeviceCentService.asyncUpdateOnlineStatus(deviceList);
            }
        }
    }


}
